#pragma once

#include "Feature.h"
#include "Timing.h"

namespace LSCM
{
    /**
     * @file FeatureBuilder.h
     * @author xingyifan
     * @date 2023-08-17 14:41
     * 
     * @description: 特征构建器
     */
    
    class FeatureBuilder
    {
    private:
        // 搜索状态，用来构建半边句柄的链表
        struct SearchStatus
        {
            Mesh::HalfedgeHandle parent; // 前一个半边的句柄
            Mesh::Normal dir;            // 半边的方向
            float valueTotal;            // 记录从链表开头到目前为止的特征和
            int depth;                   // 在链表中的深度
            bool included;               // 是否已经包含在路径中

            SearchStatus() : parent(), dir(), valueTotal(0), depth(0), included(false) {}
            SearchStatus(const Mesh::Normal &d, float v) : parent(), dir(d), valueTotal(v), depth(0), included(false) {}
        };

        // 网格状态
        enum class MeshStatus
        {
            MS_None,     // 无
            MS_Feature,  // 特征
            MS_Neighbor, // 特征邻域
        };

        // 特征集的集合
        std::vector<FeatureSet> m_featureSets;

        // 记录网格和特征度量
        Mesh *m_mesh;
        FeatureMetric *m_metric;

        // 边和半边标量句柄，用于增加属性值
        OpenMesh::EPropHandleT<Mesh::Scalar> m_featureValue;
        OpenMesh::HPropHandleT<MeshStatus> m_meshStatus;

        // 记录两个关键变量：最大规模和最小长度
        const int m_maxStringSize;
        const int m_minFeatureLength;

    public:
        FeatureBuilder(Mesh *mesh, FeatureMetric *metric, int maxSetSize = 5, int minFeatureLength = 15);
        ~FeatureBuilder();

        // 标准构建函数
        const std::vector<FeatureSet>& Build();

    private:
        void expand(const Mesh::HalfedgeHandle &halfedge, FeatureSet &featureSet);
        void tagHalfEdge(const Mesh::HalfedgeHandle &feature);
        void tagNeighborhood(const Mesh::VertexHandle &vertex);
        double depthFirst(const Mesh::HalfedgeHandle &baseEdge, HalfedgeList &path, FeatureSet &featureSet);
    };

} // namespace LSCM
